package com.iceengine.j3d.main;

/**
 * IceEngine mainclass, is used for initializing the engine.
 * @author penguin
 */
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import com.iceengine.input.keyboard.KeyboardManager;
import com.iceengine.input.keyboard.IKeyboardEvent;
import com.iceengine.input.mouse.MouseManager;
import com.iceengine.input.mouse.IMouseEvent;

public class IceEngine {
    public static int Width;
    public static int Height;
    private static KeyboardManager KeyManager;
    private static MouseManager mouseManager;
    private static BasicGameThread gameThread;
    private static Thread theGameThread;
    /**
     * Initializes the engine.
     * @param ScreenWidth Width of the screen that is drawable (windowwidth)
     * @param ScreenHeight Height of the screen that is drawable (windowheight)
     * @param fullscreen true if you want fullscreen, false if you want windowed.
     */
    public static void initEngine(int ScreenWidth, int ScreenHeight, boolean fullscreen)
    {
        try {
            Width = ScreenWidth;
            Height = ScreenHeight;
            Display.setDisplayMode(new DisplayMode(ScreenWidth, ScreenHeight));
            Display.setFullscreen(fullscreen);
            Display.create();
        } catch (Exception e) {
            e.printStackTrace();
        }
        KeyManager = new KeyboardManager();
        KeyManager.startListener();
        mouseManager = new MouseManager();
        mouseManager.startListener();
    }

    /**
     * Checks if the player want to close the game.
     * @return Is close requested.
     */
    public static boolean isEngineCloseRequested()
    {
        return Display.isCloseRequested();
    }

    /**
     * Redraw the screen.
     */
    public static void update()
    {
        Display.update();
    }

    /**
     * Stop the engine.
     */
    public static void killEngine()
    {
        KeyManager.stopListener();
        mouseManager.stopListener();
        Display.destroy();
    }

    /**
     * Initializes opengl.
     */
    public static void initGL() {
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f,((float)Width)/((float)Height),0.1f,100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glClearStencil(0);
        GL11.glLoadIdentity();

        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
    }

    /**
     * Add a keyboardevent to the keyboardevent ArrayList.
     * @param toAdd Event to add, must implement IKeyboardEvent!
     */
    public static void addKeyboardEvent(IKeyboardEvent toAdd)
    {
        KeyManager.addEvent(toAdd);
    }
    /**
     * Remove a keyboardevent from the keyboardevent ArrayList.
     * @param toAdd Event to remove, must implement IKeyboardEvent!
     */
    public static void removeKeyboardEvent(IKeyboardEvent toRemove)
    {
        KeyManager.removeEvent(toRemove);
    }
    /**
     * Add a mouseevent to the mouseevent ArrayList.
     * @param toAdd Event to add, must implement IMouseEvent!
     */
    public static void addMouseEvent(IMouseEvent toAdd)
    {
        mouseManager.addEvent(toAdd);
    }
    /**
     * Remove a mouseevent from the mouseevent ArrayList.
     * @param toAdd Event to remove, must implement IMouseEvent!
     */
    public static void removeMouseEvent(IMouseEvent toRemove)
    {
        mouseManager.removeEvent(toRemove);
    }
    /**
     * Run a game in it's own thread.
     * @param toRun Game to run.
     */
    public static void runGame(BasicGame toRun)
    {
        gameThread = new BasicGameThread(toRun);
        theGameThread = new Thread(gameThread);
        theGameThread.run();
    }
    /**
     * Stop game thread.
     */
    public static void stopGame()
    {
        theGameThread.stop();
    }
}
